package com.yhq.spring.websocket.parser;

import com.alibaba.fastjson.JSON;
import com.yhq.spring.websocket.constants.TypeConstants;
import com.yhq.spring.websocket.parser.model.HKConvertReq;
import com.yhq.spring.websocket.parser.model.HkConvertRes;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.socket.*;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * 粤语转中文
 * @author hqyin
 * @date 2024/11/20 11:34 AM
 */
@Slf4j
public class HK2TextHandler implements WebSocketHandler {
    private String voicePath;
    private String result;
    //超时时间默认20s，TODO：可配置到配置文件中
    private long timeOut = 20*1000;
    private Integer code;
    private String msg;

    public HK2TextHandler(String voicePath) {
        this.voicePath = voicePath;
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        //连接建立后的处理逻辑
        log.info("连接建立后的处理逻辑");
        //发送解析初始标记
        HKConvertReq req = new HKConvertReq();
        req.setSignal("start");
        req.setAppId("app_hk_test");
        req.setPunctuation(2);
//        req.setContinuousDecoding(true);
//        req.setSpeechPauseTime(500);
//        req.setServerVad(true);
//        req.setCacheFrame(true);
        req.setAudioType("MP3");
        String data = JSON.toJSONString(req);
        log.info("发送消息：{}",data);
        WebSocketMessage<String> message = new TextMessage(data.getBytes(StandardCharsets.UTF_8));
        session.sendMessage(message);
    }

    public String getParserResult(){
        long waitTime = System.currentTimeMillis() + timeOut;
        while (code == null && System.currentTimeMillis()<waitTime) {

        }
        if(code == null) {
            throw new RuntimeException("解析超时，请重新尝试");
        }

        if(200 == code) {
            return result;
        }

        throw new RuntimeException(msg);

    }

    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
        // 处理来自服务器的消息
        log.info("服务器返回结果：{}",message.getPayload());
        HkConvertRes res = JSON.parseObject(message.getPayload().toString(),HkConvertRes.class);
        switch (res.getType()) {
            case TypeConstants.SERVER_READY:
                sendMP3Data(session);
                sendEndSpeech(session);
                break;
            case TypeConstants.FINAL_RESULT:
                if("ok".equals(res.getStatus()))  {
                    result = res.getResult();
                    code = 200;
                } else {
                    code = 500;
                    msg = res.getMessage();
                }

                break;
            case TypeConstants.SPEECH_END:
                break;
            case TypeConstants.PARTIAL_RESULT:
                break;
            default:
        }
    }




    private void sendEndSpeech(WebSocketSession session) throws IOException {
        //传输完成
        HKConvertReq req2 = new HKConvertReq();
        req2.setSignal("end");
        String data2 = JSON.toJSONString(req2);
        log.info("发送消息：{}",data2);
        WebSocketMessage<String> msg2 = new TextMessage(data2.getBytes(StandardCharsets.UTF_8));
        session.sendMessage(msg2);
    }

    private void sendMP3Data(WebSocketSession session)  {
        try {
            Path path = Paths.get(voicePath);
            byte[] bytes= Files.readAllBytes(path);
            WebSocketMessage<ByteBuffer> msg = new BinaryMessage(bytes);
            session.sendMessage(msg);
        } catch (IOException e) {
            code = 500;
            msg = "发送消息失败";
            throw new RuntimeException(e);
        }

    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        // 处理传输错误
        log.error("处理传输错误",exception);
        code = 500;
        msg = "传输错误，请联系管理员";

    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        //连接关闭后的处理逻辑
        log.info("连接关闭后的处理逻辑：{}",JSON.toJSONString(closeStatus));

    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }

}
